package cn.tedu.springrabbitmq.m6;

import com.rabbitmq.client.*;


import java.io.IOException;
import java.util.Scanner;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeoutException;

public class Client {
    public static void main(String[] args) throws Exception {
        System.out.print("求第几个斐波那契数：");
        int n = new Scanner(System.in).nextInt();
        long r = f(n);
        System.out.println("第"+n+"个斐波那契数："+r);
    }

    private static long f(int n) throws IOException, TimeoutException, InterruptedException {
        ArrayBlockingQueue<Long> abq = new ArrayBlockingQueue<>(10);
        // 连接
        ConnectionFactory f = new ConnectionFactory();
        f.setHost("192.168.64.140");  // wht6.cn
        f.setPort(5672);
        f.setUsername("admin");
        f.setPassword("admin");
        Channel c = f.newConnection().createChannel();
        // 创建调用队列： rpc-queue
        c.queueDeclare("rpc-queue",false,false,false,null);
        // 创建随机队列，用来获取计算结果
        String replyTo = c.queueDeclare().getQueue();
        // 产生一个关联id
        String cid = UUID.randomUUID().toString();
        // 发送调用信息，携带两个参数：返回队列名、关联id
        AMQP.BasicProperties prop =
                new AMQP.BasicProperties.Builder()
                        .replyTo(replyTo)  // 返回队列名
                        .correlationId(cid)  // 关联id
                        .build();

        c.basicPublish("", "rpc-queue", prop, (n+"").getBytes());

        // 执行其他运算............
        System.out.println("执行其他运算............");

        // 需要结果时，从返回队列接收计算结果
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            // 消费者线程处理计算结果
            // message中的关联id，是不是刚才发送的关联id
            if (cid.equals(message.getProperties().getCorrelationId())) {
                String s = new String(message.getBody());
                // 把结果放入 BlockingQueue
                abq.add(Long.valueOf(s));
            }
        };
        CancelCallback cancelCallback = consumerTag -> {};
        c.basicConsume(replyTo, true, deliverCallback, cancelCallback);
        // 主线程中，从 BlockingQueue 获取数据
        return abq.take();

    }

}
